package face.util;

import org.bytedeco.javacpp.opencv_core.Mat;
import org.bytedeco.javacpp.opencv_core.Point2fVector;
import org.bytedeco.javacpp.opencv_core.Point2fVectorVector;
import org.bytedeco.javacpp.opencv_core.RectVector;
import org.bytedeco.javacpp.opencv_core.Scalar;
import org.bytedeco.javacpp.opencv_face;
import org.bytedeco.javacpp.opencv_face.Facemark;
import org.bytedeco.javacpp.opencv_face.FacemarkLBF;
import org.bytedeco.javacpp.opencv_imgproc;

/**
 * 检测人脸的68个特征点
 * @author ShiQiang
 *
 */
public class FaceKeyPoints { 
	// 加载人脸检测器（Face Detector）
	// [1]Haar Face Detector
	// CascadeClassifier faceDetector("haarcascade_frontalface_alt2.xml");
	// [2]LBP Face Detector 
	// 创建Facemark类的对象
	static Facemark facemark = FacemarkLBF.create();
	
	static{  
		facemark.loadModel(PathUtil.getFilePath(Common.facePointModelPath));
	}
	
	public static Point2fVectorVector piontsSixEight(Mat frame){
		Mat gray = new Mat();   
		// 将视频帧转换至灰度图, 因为Face Detector的输入是灰度图
		opencv_imgproc.cvtColor(frame, gray, opencv_imgproc.COLOR_BGR2GRAY); 
		// 存储人脸矩形框的容器
		RectVector faces = CheckFaceAndEye.findFaces(gray); 
		// 人脸关键点的容器
		Point2fVectorVector landmarks = new Point2fVectorVector();
		boolean success = faces != null;
		if(success){ 
			// 运行人脸关键点检测器（landmark detector）
			success = facemark.fit(frame, faces, landmarks);
		}
		
		if(success){
			return landmarks;
		}else{
			return null;
		}
		
	}
	//Horizontal
	public static Mat horizontalFace(Mat frame) { 
		// 人脸对齐
		Point2fVectorVector landmarks = piontsSixEight(frame); 
		
		if(landmarks == null){
			return frame;
		}
		
		for (int i = 0; i < landmarks.get().length; i++) {
			Point2fVector points = landmarks.get()[i];
			frame = Facealignment.getwarpAffineImg(frame,points);
		}
		return frame; 
	}
	
	
	public static void drawPoints(Mat frame) { 
		 
		// 人脸关键点的容器
		Point2fVectorVector landmarks = piontsSixEight(frame); 
		
		if (landmarks != null) {
			//2 如果成功, 在视频帧上绘制关键点
			for (int i = 0; i < landmarks.get().length; i++) {
				// 自定义绘制人脸特征点函数, 可绘制人脸特征点形状/轮廓 
				// OpenCV自带绘制人脸关键点函数: drawFacemarks
				Point2fVector points = landmarks.get()[i];
				frame = DrawLandmarks.drawLandmarks(frame,points); 
				opencv_face.drawFacemarks(frame,points, new Scalar(0, 0, 255,0));
			}
		} 
	}
	 
}
